package com.billard.utils;

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.SecureRandom;
import java.util.Base64;


//盐加密
public class SaltUtil {
    //防止被继承篡改
    private static final SecureRandom SECURE_RANDOM = new SecureRandom();//生成盐值 高随机性,Java 提供的一个强加密安全的伪随机数生成器

    private static final int  ITERATION_COUNT = 65536;//设置 PBKDF2 算法的迭代次数为 65,536 次。

    private static final int  KEY_LENGTH = 256;//指定最终生成的密钥（即密码哈希值）的长度为 256 位


    private static final String ALGORITHM = "PBKDF2WithHmacSHA256";   //这是一种基于 HMAC 和 SHA-256 的 PBKDF2 实现

    private static final int SALT_LENGTH_BYTE = 16;    //指定生成盐的长度（以字节为单位）

        //造盐
        public static String createSalt(){
            byte[] salt = new byte[SALT_LENGTH_BYTE ];//创建字节数组
            SECURE_RANDOM.nextBytes(salt);//用安全随机数填充个
            return Base64.getEncoder().encodeToString(salt);//转换成文本
        }


        //生成哈希(盐+密码）
        public static String hashPassword(String password,String salt)  {

           try {
               byte[] saltBytes = Base64.getDecoder().decode(salt);//解码
               //创建规格
               PBEKeySpec spec = new PBEKeySpec(password.toCharArray(),saltBytes,ITERATION_COUNT,KEY_LENGTH);
               SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM); // 3. 获取工厂
               byte[] hash = factory.generateSecret(spec).getEncoded(); // 4. 执行计算
               return Base64.getEncoder().encodeToString(hash); // 5. 编码哈希
           }
           catch (Exception e){
               throw new RuntimeException("计算失败");
           }
        }
        //验证用户输入的密码是否与存储的盐和哈希值匹配。
        public static boolean verifyPassword(String inputPassword, String storedSalt, String passwordHash) {
            try {
            String calculatedHash = hashPassword(inputPassword, storedSalt);//输入的密码和数据库里的盐
            return (calculatedHash.equals(passwordHash));//与数据库里的密码对比哈希值
            } catch (Exception e) {
            return false;
             }
         }


}
